package com.daichi.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.daichi.common.dto.SysMenuDto;
import com.daichi.common.lang.Const;
import com.daichi.common.lang.Result;
import com.daichi.entity.SysMenu;
import com.daichi.entity.SysRoleMenu;
import com.daichi.entity.SysUser;
import com.daichi.mapper.SysMenuMapper;
import com.daichi.mapper.SysRoleMenuMapper;
import com.daichi.mapper.SysUserMapper;
import com.daichi.service.SysMenuService;
import com.daichi.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Daichi Chou
 * @since 2021-06-05
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    private final SysMenuMapper sysMenuMapper;

    private final SysUserMapper sysUserMapper;

    private final RedisUtil redisUtil;

    private final SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    public SysMenuServiceImpl(SysMenuMapper sysMenuMapper, SysUserMapper sysUserMapper, RedisUtil redisUtil, SysRoleMenuMapper sysRoleMenuMapper) {
        this.sysMenuMapper = sysMenuMapper;
        this.sysUserMapper = sysUserMapper;
        this.redisUtil = redisUtil;
        this.sysRoleMenuMapper = sysRoleMenuMapper;
    }

    @Override
    public List<SysMenuDto> getUserNav(SysUser sysUser) {

        List<Long> menuIds = sysUserMapper.getNavMenuIds(sysUser.getId());

        if (CollectionUtil.isEmpty(menuIds)) {
            return Collections.emptyList();
        }

        return sysMenuMapper.getUserNavByMenuIds(menuIds);

//        return anotherMethod(menuIds);

    }

    @Override
    public List<SysMenu> getTreeList() {

        if (redisUtil.hasKey(Const.REDIS_MENU_TREE_KEY)) {
            return JSON.parseArray(redisUtil.getString(Const.REDIS_MENU_TREE_KEY),SysMenu.class);
        }

        List<SysMenu> treeList = sysMenuMapper.getTreeList();

        redisUtil.set(Const.REDIS_MENU_TREE_KEY, treeList, 60 * 60);

        return treeList;
    }

    public void clearTreeList() {
        redisUtil.del(Const.REDIS_MENU_TREE_KEY);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteById(Long id) {

        if (this.count(new QueryWrapper<SysMenu>().eq("parent_id", id)) > 0) {
            return Result.fail("请先删除子菜单");
        }

        sysRoleMenuMapper.delete(new QueryWrapper<SysRoleMenu>().eq("menu_id", id));

        boolean success = this.removeById(id);

        if (!success) {
            return Result.fail("删除失败");
        }

        return Result.succ("删除成功");
    }

    private List<SysMenuDto> anotherMethod(List<Long> menuIds) {

        List<SysMenu> menus = this.listByIds(menuIds);

        // 转树状结构
        List<SysMenu> menuTree = buildTreeMenu(menus);

        // 实体转DTO
        return convert(menuTree);

    }

    private List<SysMenuDto> convert(List<SysMenu> menuTree) {
        List<SysMenuDto> menuDtoList = new ArrayList<>();

        menuTree.forEach(m -> {
            SysMenuDto dto = new SysMenuDto();

            dto.setId(m.getId());
            dto.setName(m.getPerms());
            dto.setTitle(m.getName());
            dto.setComponent(m.getComponent());
            dto.setPath(m.getPath());

            if (m.getChildren().size() > 0) {

                // 子节点调用当前方法进行再次转换
                dto.setChildren(convert(m.getChildren()));
            }

            menuDtoList.add(dto);
        });

        return menuDtoList;
    }

    private List<SysMenu> buildTreeMenu(List<SysMenu> menus) {

        List<SysMenu> finalMenus = new ArrayList<>();

        // 先各自寻找到各自的孩子
        for (SysMenu menu : menus) {

            for (SysMenu e : menus) {
                if (Objects.equals(menu.getId(), e.getParentId())) {
                    menu.getChildren().add(e);
                }
            }

            // 提取出父节点
            if (menu.getParentId() == 0L) {
                finalMenus.add(menu);
            }
        }

        System.out.println(JSONUtil.toJsonStr(finalMenus));
        return finalMenus;
    }

}
